package com.ruoyi.web.controller.qqLoginAndPayByHTQ;



import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ruoyi.Money.service.IMoneyService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.PhoneLoginService;
import com.ruoyi.system.util.DateUtil;
import com.ruoyi.system.util.HttpsUtil;
import com.ruoyi.system.util.PayCommonUtil;
import com.ruoyi.system.util.StringUtil;

@Controller
@RequestMapping(value = "/a/data/qqPay")
public class qqPayController {
	@Autowired
	private PhoneLoginService phoneLoginService;
	
	@Autowired
	private IMoneyService moneyService;

	private String appids = qqLoginConfig.AppID;;

	private String appsecret = qqLoginConfig.AppSecert;

	private String mch_id = qqLoginConfig.mch_id;

	private String MerchantKey = qqLoginConfig.MerchantKey;

	private String urls = "https://bangbang.laigl.com/a/data/qqPay/huidiao";
	
	@RequestMapping(value="/api/zf")
	@ResponseBody
	public Map<String, Object> dqsfs(
			@RequestParam(value = "jes", required = true) String jes,
			@RequestParam(value = "order_id", required =false ) String order_id,
			@RequestParam(value = "uid", required =true ) String uid,
			@RequestParam(value = "lx", required =true ) String lx,
			HttpServletRequest request, HttpServletResponse response) {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		String s8 = formatter.format(currentTime);
		HttpSession session = request.getSession();
		if(StringUtils.isEmpty(order_id)){
			order_id= "ZF"+s8+((int)((Math.random()*9+1)*100000))+lx;
		} else {
			order_id=order_id+lx;
		}
		String openid = phoneLoginService.CallShellProcedure("R2006004|" + uid)
				.get(0).get("openid").toString();
		// oWbqL1T3O975WcrubVVpxcKVv7CU
		

		System.out.println(openid);
		Map<String, Object> returnMap = new HashMap<String, Object>();
		String appId = appids;
		String body = "校园帮帮支付";
		String merchantId = mch_id;
		String tradeNo = order_id;
		String nonceStr1 = createNonceStr();
		String notifyUrl = urls;
		String openId = openid;
		String totalFee = jes;
		System.err.println("totalFee=================="+totalFee);
		String IFCONFIG = getIP.getIpconfig();
		TreeMap<String, String> map = new TreeMap<String, String>();
		map.put("appid", appId);
		map.put("mch_id", merchantId);
		map.put("device_info", "WEB");
		map.put("body", body);
		map.put("trade_type", "NATIVE");
		map.put("nonce_str", nonceStr1);
		map.put("notify_url", notifyUrl);
		map.put("out_trade_no", tradeNo);
		map.put("total_fee", totalFee);
		map.put("openid", openId);
		map.put("spbill_create_ip", IFCONFIG);
		map.put("fee_type", "CNY");
		String sign = createSign(map);
		
		

		String xml = "<xml>" + "<appid>" + appId + "</appid>" + "<body>" + body
				+ "</body>" + "<device_info>"+"WEB"+"</device_info>" + "<mch_id>"
				+ merchantId + "</mch_id>" + "<nonce_str>" + nonceStr1
				+ "</nonce_str>" + "<notify_url>" + notifyUrl + "</notify_url>"
				+ "<openid>" + openId + "</openid>" + "<out_trade_no>"
				+ tradeNo + "</out_trade_no>" + "<total_fee>" + totalFee + "</total_fee>" 
				+ "<sign>" + sign + "</sign>" + "<fee_type>" + "CNY" + "</fee_type>"
				+ "<trade_type>" + "NATIVE" + "</trade_type>" 		
				+ "<spbill_create_ip>"+ IFCONFIG + "</spbill_create_ip>" 
				+ "</xml>";
		
		
		
		System.out.println(xml);
		String url = "https://qpay.qq.com/cgi-bin/pay/qpay_unified_order.cgi";

		String result = null;

		result = HttpsUtil.httpsRequestToString(url, "POST", xml);
		System.out.println(result);
		String reg = "<prepay_id><!\\[CDATA\\[(\\w+)\\]\\]></prepay_id>";

		Pattern pattern = Pattern.compile(reg);
		System.out.println(result);
		Matcher matcher = pattern.matcher(result);

		String prepayId = "";

		while (matcher.find()) {

			prepayId = matcher.group(1);

			System.out.println("预支付ID：" + prepayId);
		}
		Date beijingDate = Calendar.getInstance(Locale.CHINA).getTime();
		String datassss = String.valueOf(beijingDate.getTime() / 1000);
		String nonceStrss = createNonceStr();
		// appId, timeStamp, nonceStr, package, signType
		// paySign=MD5(appId=${appid}&nonceStr=${nonceStr}&package=prepay_id=${prepay_id}&signType=MD5&timeStamp=${timeStamp}&key=${key}).toString().toUpperCase();
		String stringAs = "appId=" + appids + "&nonceStr=" + nonceStrss
				+ "&package=prepay_id=" + prepayId + "&signType=MD5&timeStamp="
				+ datassss + "&key=" + MerchantKey;
		System.out.println(stringAs);
		String dd = null;
		try {
			dd = MD5(stringAs).toUpperCase();
		} catch (Exception e) {
			e.printStackTrace();
		}
		List<Map<String, Object>> list = phoneLoginService
				.CallShellProcedure("R2009006|" + openId + "|" + datassss + "|"
						+ jes + "|" + tradeNo);

		returnMap.put("paySignss", dd);
		returnMap.put("appids", appids);
		returnMap.put("timestampss", datassss);
		returnMap.put("nonceStrss", nonceStrss);
		returnMap.put("packagess", "prepay_id=" + prepayId);
		returnMap.put("signTypess", "MD5");
		returnMap.put("tradeNo", tradeNo);

		return returnMap;
	}
	
	@RequestMapping(value = "/huidiao")
	@ResponseBody
	public String  huidiao(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
		System.out.println("QQ支付回调");
		InputStream inStream = request.getInputStream();
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		String resultxml = new String(outSteam.toByteArray(), "utf-8");
		System.out.println(resultxml);

		Map<String, String> params = PayCommonUtil.doXMLParse(resultxml);
		// outSteam.close();
		//inStream.close();


		Map<String,String> return_data = new HashMap<String,String>();
		
			
	
			System.out.println("===============付款成功==============");
			// ------------------------------
			String openids = params.get("openid");
			String total_fee = params.get("total_fee");
			double v = Double.valueOf(total_fee) / 100;
			String tradeNo = params.get("transaction_id");
			String out_trade_no = params.get("out_trade_no");
			List<Map<String, Object>> lists =  phoneLoginService.CallShellProcedure("R2009007|"+openids+"|"+out_trade_no+"|"+out_trade_no+"|"+total_fee);
			
			Object t1=lists.get(0).get("pds");
			Date accountTime = DateUtil.stringtoDate(params.get("time_end"), "yyyyMMddHHmmss");
			String ordertime = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
			String totalAmount = String.valueOf(v);
			String appId = params.get("appid");
			/*HttpSession session = request.getSession();
			String oid=session.getAttribute("oid").toString();
			List<Map<String, Object>> listss=  phoneLoginService.CallShellProcedure("R2016006|"+openids+"|"+oid+"|"+total_fee);
*/

			return_data.put("return_code", "SUCCESS");
			return_data.put("return_msg", "OK");
			return StringUtil.GetMapToXML(return_data);		
	}

	/**
	 * 生成 MD5
	 *
	 * @param data
	 *            待处理数据
	 * @return MD5结果
	 */
	public static String MD5(String data) throws Exception {
		MessageDigest md = MessageDigest.getInstance("MD5");
		byte[] array = md.digest(data.getBytes("UTF-8"));
		StringBuilder sb = new StringBuilder();
		for (byte item : array) {
			sb.append(Integer.toHexString((item & 0xFF) | 0x100)
					.substring(1, 3));
		}
		return sb.toString().toUpperCase();
	}

	/**
	 * 生成随机数
	 * <p>
	 * 算法参考：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
	 * </p>
	 * 
	 * @return 随机数字符串
	 */

	public static String createNonceStr() {
		SecureRandom random = new SecureRandom();
		int randomNum = random.nextInt();
		return Integer.toString(randomNum);
	}

	/**
	 * 生成签名，用于在微信支付前，获取预支付时候需要使用的参数sign
	 * <p>
	 * 算法参考：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
	 * </p>
	 * 
	 * @param params
	 *            需要发送的所有数据设置为的Map
	 * @return 签名sign
	 */

	public String createSign(TreeMap<String, String> params) {
		String signValue = "";
		String stringSignTemp = "";

		String stringA = "";
		// 获得stringA
		/*Set<String> keys = params.keySet();
		for (String key : keys) {
			stringA += (key + "=" + params.get(key) + "&");
		}*/
		/*TreeMap<String, Object> map = new TreeMap<String, Object>();
		map.put("appid", appId);
		map.put("mch_id", merchantId);
		map.put("device_info", "WEB");
		map.put("body", body);
		map.put("trade_type", "APP");
		map.put("nonce_str", nonceStr1);
		map.put("notify_url", notifyUrl);
		map.put("out_trade_no", tradeNo);
		map.put("total_fee", totalFee);
		map.put("openid", openId);
		map.put("spbill_create_ip", IFCONFIG);
		map.put("fee_type", "CNY");*/
		
		String appid=params.get("appid");
		String mch_id=params.get("mch_id");
		String device_info=params.get("device_info");
		String body=params.get("body");
		String trade_type=params.get("trade_type");
		String nonce_str=params.get("nonce_str");
		String notify_url=params.get("notify_url");
		String out_trade_no=params.get("out_trade_no");
		String total_fee=params.get("total_fee");
		String openid=params.get("openid");
		String spbill_create_ip=params.get("spbill_create_ip");
		String fee_type=params.get("fee_type");
		
		
		stringA="appid" + "=" + appid + "&" +
				"body" + "=" + body + "&" +
				"device_info" + "=" + device_info + "&"+
				"fee_type" + "=" + fee_type + "&" +									
				"mch_id" + "=" + mch_id + "&"+
				"nonce_str" + "=" + nonce_str + "&" +
				"notify_url" + "=" + notify_url + "&" +
				"openid" + "=" + openid + "&" +
				"out_trade_no" + "=" + out_trade_no + "&" +
				"spbill_create_ip" + "=" + spbill_create_ip + "&" +
				"total_fee" + "=" + total_fee + "&" +				
				"trade_type" + "=" + trade_type ;
						
		//stringA = stringA.substring(0, stringA.length() - 1);
		// 获得stringSignTemp
		stringSignTemp = stringA + "&key=" + MerchantKey;
		// 获得signValue
		signValue = encryptByMD5(stringSignTemp).toUpperCase();
		System.out.println(stringSignTemp);	
		System.out.println("预支付签名：" + signValue);
		return signValue;
	}

	/**
	 * MD5加密
	 * 
	 * @param sourceStr
	 * @return
	 */

	public static String encryptByMD5(String sourceStr) {
		String result = "";
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(sourceStr.getBytes("UTF-8"));
			byte b[] = md.digest();
			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			result = buf.toString();
		} catch (NoSuchAlgorithmException e) {
			System.out.println(e);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	}

	public static String GetResponse(String path, String Info, String xml)
			throws IOException {

		// 1, 得到URL对象
		URL url = new URL(path);

		// 2, 打开连接
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();

		// 3, 设置提交类型
		conn.setRequestMethod(Info);
		conn.setRequestProperty("Content-Type", "text/xml");

		// 4, 设置允许写出数据,默认是不允许 false
		conn.setDoOutput(true);
		conn.setDoInput(true);// 当前的连接可以从服务器读取内容, 默认是true

		// 5, 获取向服务器写出数据的流
		OutputStream os = conn.getOutputStream();
		// 参数是键值队 , 不以"?"开始
		os.write(xml.getBytes());
		// os.write("googleTokenKey=&username=admin&password=5df5c29ae86331e1b5b526ad90d767e4".getBytes());
		os.flush();
		// 6, 获取响应的数据
		// 得到服务器写回的响应数据
		BufferedReader br = new BufferedReader(new InputStreamReader(
				conn.getInputStream(), "utf-8"));
		String str = br.readLine();
		// System.out.println("响应内容为:  " + str);

		return str;
	}
	/*
	 * public String creatPostAndTransData(String path,String Info,String xml) {
	 * String urlStr = ""; String line = ""; StringBuffer resultSting = new
	 * StringBuffer(); try { //urlStr,写在了配置文件中,直接进行获取 urlStr = path; //声明URL URL
	 * url = new URL(urlStr); //1.创建链接 URLConnection con = url.openConnection();
	 * //2.封装报文传输进行传输 //调用getXmlInfo(Map<String, Object> dataMap)进行报文的封装 String
	 * xmlInfo = xml; byte[] xmlData = xmlInfo.getBytes();
	 * con.setDoOutput(true); con.setDoInput(true); con.setUseCaches(false);
	 * con.setRequestProperty("Pragma:", "no-cache");
	 * con.setRequestProperty("Cache-Control", "no-cache");
	 * con.setRequestProperty("Content-Type", "text/xml");
	 * con.setRequestProperty("Content-length",String.valueOf(xmlData.length));
	 * OutputStreamWriter out = new OutputStreamWriter( con.getOutputStream());
	 * System.out.println(">>>>>>>>>>接口地址为urlStr=" + urlStr);
	 * System.out.println(">>>>>>>>>>传入的报文xmlInfo=" + xmlInfo); out.write(new
	 * String(xmlInfo.getBytes("ISO-8859-1"))); out.flush(); out.close();
	 * //3.获取返回报文 BufferedReader br = new BufferedReader(new InputStreamReader(
	 * con.getInputStream())); //对返回值报文进行打印 for (line = br.readLine(); line !=
	 * null; line = br.readLine()) { //对返回的报文进行结果判断<RspCode>0000</RspCode>
	 * System.out.println(">>>>>>>>>>>>>>>>>>>返回的结果报文内容为:---------"+line);
	 * //对返回的报文进行拼接,然后返回给业务层,在业务层进行判断 resultSting.append(line); } return
	 * resultSting.toString(); } catch (MalformedURLException e) {
	 * e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
	 * return resultSting.toString(); }
	 */

}
